import socket from '@ohos.net.socket';
import wifiManager from '@ohos.wifiManager';

export interface MessageCallback {
  (message: string): void;
}

export interface StatusCallback {
  (isConnected: boolean): void;
}

export class TcpClientHelper {
  tcp: socket.TCPSocket;
  serverNetAddress: socket.NetAddress;

  connectTcpServer(address: string, port: number, statusCallback: StatusCallback, messageCallback: MessageCallback) {
    this.tcp = socket.constructTCPSocketInstance();
    this.serverNetAddress = {
      address: address,
      port: port
    }

    // 订阅TCPSocket相关的订阅事件
    this.tcp.on('message', value => {
      console.log("on message");
      let buffer = value.message;
      let dataView = new DataView(buffer);
      let str = "";
      for (let i = 0; i < dataView.byteLength; ++i) {
        str += String.fromCharCode(dataView.getUint8(i));
      }
      console.log("on connect received:" + str);
      messageCallback(str);
    });
    this.tcp.on('connect', () => {
      console.log("on connect");
      statusCallback(true);
    });
    this.tcp.on('close', () => {
      console.log("on close");
      statusCallback(false);
    });

    // 获取本机 IP
    let localAddress = resolveIP(wifiManager.getIpInfo().ipAddress);
    // 绑定本机 IP
    this.tcp.bind({ address: localAddress }, err => {
      if (err) {
        console.log('connect fail');
        return;
      }
      console.log('connect success');

      // 连接到目标 IP
      this.tcp.connect({ address: this.serverNetAddress, timeout: 6000 })
        .then(() => {
          console.info('Connect success.');
        }).catch((error) => {
        console.error(`Connect failed. ${JSON.stringify(error)}`);
      });
    });
  }

  sendMessage(message: string) {
    if (this.tcp !== undefined) {
      this.tcp.send({ data: message })
    }
  }

  stop() {
    if (this.tcp !== undefined) {
      this.tcp.close((err) => {
        if (err) {
          console.log('close socket failed. ' + JSON.stringify(err));
        }
        console.log('close socket.')
      });
      this.tcp.off('message');
      this.tcp.off('connect');
      this.tcp.off('close');
    }
  }
}

function resolveIP(ip: number): string {
  if (ip < 0 || ip > 0xFFFFFFFF) {
    throw ('The number is not normal!');
  }
  return (ip >>> 24) + '.' + (ip >> 16 & 0xFF) + '.' + (ip >> 8 & 0xFF) + '.' + (ip & 0xFF);
}